﻿Imports CrystalReportViewer
Imports System.Xml
Imports System.Reflection
Imports System.Resources

''' <summary>
''' Loads report definitiions from an operating system file
''' </summary>
''' <remarks>
''' Example usage:
''' dim c as new XMLFileReportDefinitionsProvider()
''' c.setFilename("c:\path\IIC.ReportMenu.xml")
''' </remarks>
Public Class XMLFileReportDefinitionsProvider
    Inherits XMLResourceReportDefinitionsProvider
    Implements ICrystalReportMatadataProvider

    Protected Overrides Function openStream() As IO.Stream

        Return System.IO.File.OpenRead(_fileName)

    End Function


End Class

''' <summary>
''' Loads report definitiions from an xml resource file
''' The resource should be an "EmbeddedResource"
''' </summary>
''' <remarks>
''' Example usage:
''' dim c as new XMLResourceReportDefinitionsProvider()
''' c.setFilename("IIC.ReportMenu.xml")
''' </remarks>
Public Class XMLResourceReportDefinitionsProvider
    Implements ICrystalReportMatadataProvider

    Protected _reports As List(Of ReportMatadata)

    Protected _fileName As String

    Private Const XML_EMENT_REPORT As String = "Report"

    Public Property criteriaProvider As ICriteriaProvider = New XMLCriteriaProvider _
                                            Implements ICrystalReportMatadataProvider.criteriaProvider

    Protected Sub loadReports(ByVal myXmlDocument As XmlDocument)

        Dim cnodes As XmlNodeList = myXmlDocument.GetElementsByTagName(XML_EMENT_REPORT)

        For Each node As XmlNode In cnodes

            Dim cr As ReportMatadata = New ReportMatadata
            Dim xnode As XmlNode = node.SelectSingleNode("Key")
            If xnode IsNot Nothing Then
                cr.ReportKey = xnode.InnerText
            End If

            xnode = node.SelectSingleNode("Assembly")
            If xnode IsNot Nothing Then
                cr.ReportAssemblyName = xnode.InnerText
            End If

            xnode = node.SelectSingleNode("FullyQualifiedResourcePath")
            If xnode IsNot Nothing Then
                cr.FullyQualifiedResourcePath = xnode.InnerText
            End If
            xnode = node.SelectSingleNode("DisplayName")
            If xnode IsNot Nothing Then
                cr.DisplayName = xnode.InnerText
            End If
            xnode = node.SelectSingleNode("DisplayOrder")
            If xnode IsNot Nothing Then
                cr.DisplayOrder = CInt(xnode.InnerText)
            End If

            Dim elmtNode As XmlElement = CType(node.SelectSingleNode("Criteria"), XmlElement)
            If elmtNode IsNot Nothing Then
                cr.Criteria = Me.criteriaProvider.loadCriteriaDefinitions(elmtNode)
            End If

            If String.IsNullOrEmpty(cr.ReportKey) Then
                Throw New ApplicationException("Report Definitions require a Key element with a unique value.")
            End If

            _reports.Add(cr)
        Next

        _reports.Sort()

    End Sub

    Public Sub setFileOrResourceName(ByVal v As String)
        Me._fileName = v
    End Sub

    Protected Overridable Function openStream() As IO.Stream

        Dim iss As IO.Stream = Assembly.GetEntryAssembly.GetManifestResourceStream(_fileName)
        Return iss

    End Function

    Public Function getSystemReports() As List(Of ReportMatadata) _
        Implements CrystalReportViewer.ICrystalReportMatadataProvider.getSystemReports

        'only load reports once!
        If Me._reports Is Nothing Then

            Me._reports = New List(Of CrystalReportViewer.ReportMatadata)

            Dim myXmlDocument As XmlDocument = New XmlDocument()
            Dim iss As IO.Stream = Nothing

            Try
                iss = Me.openStream()
                myXmlDocument.Load(iss)

                Me.loadReports(myXmlDocument)

            Finally

                If iss Is Nothing = False Then
                    iss.Close()
                End If
            End Try

        End If

        Return _reports

    End Function

    ''' <summary>
    ''' Returns a report metadata object from the cache
    ''' </summary>
    ''' <param name="reportKey">The key of the report</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getSystemReportByKey(ByVal reportKey As String) As  _
                ReportMatadata Implements ICrystalReportMatadataProvider.getSystemReportByKey

        Return Me.getSystemReports().FirstOrDefault(Function(x)
                                                        Return x.ReportKey = reportKey
                                                    End Function)

    End Function

   

End Class
